#if defined(_WIN32) || defined(_WIN64)
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include <iostream>
#include <cstdio>
#include <thread>
#include <mutex>

std::mutex fileMutex;

int file_process(const std::string& filename) {
    FILE* file = fopen(filename.c_str(), "r");
    if (file != nullptr) {
        fclose(file);
        return 1; // 文件存在且可读
    } else {
        if (errno == ENOENT) {
            return 0; // 文件不存在
        } else {
            return 2; // 文件不可读
        }
    }

}

void threadFunc(int threadId)
{
#if defined(_WIN32) || defined(_WIN64)
    Sleep(rand() % 10);
#else
    usleep(100 * (rand() % 10));
#endif
    std::lock_guard<std::mutex> lock(fileMutex);
    int status_file = file_process("test.txt");
    switch(status_file)
    {
        case 0:
        {
            FILE* file = fopen("test.txt", "w");
            if (file != nullptr) {
                fprintf(file, "Hello world from thread %d\n", threadId);
                fclose(file);
            }
        }
        break;
        case 1:
        {
            fileMutex.unlock();
            FILE* file = fopen("test.txt", "r");
            if (file != nullptr) {
                int x;
                fscanf(file, "Hello world from thread %d", &x);
                fclose(file);
                printf("thread %d read %d\n", threadId, x);
            }
        }
        break;
        default:
            printf("Can not read file, program will exit.\n");
            exit(1);
        break;
    }
}

int main() {
    srand(time(0));
    std::thread t1(threadFunc, 1);
    std::thread t2(threadFunc, 2);
    std::thread t3(threadFunc, 3);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}
